package com.example.controller;

import com.example.Utils.OrderWSUtil;
import com.example.dao.MenuMapper;
import com.example.service.impl.MenuServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

@Component
public class OrderWebSocketHandler extends TextWebSocketHandler {
    private static final Map<String,CopyOnWriteArrayList<WebSocketSession>> sessionsMap =new ConcurrentHashMap<>();
    //private final CartServiceImpl cartService;
    @Autowired
    private OrderWSUtil orderWSUtil;

    private static final CopyOnWriteArrayList<WebSocketSession> sessions = new CopyOnWriteArrayList<>();

    ObjectMapper objectMapper=new ObjectMapper();

    @Autowired
    private MenuServiceImpl menuService;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // sessions.add(session);
    }

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        Map<String,Object> map =new ObjectMapper().readValue(message.getPayload(),Map.class);
        String tableId="tableId"+(String) map.get("tableId");
        sessionsMap.computeIfAbsent(tableId,k->new CopyOnWriteArrayList<>()).addIfAbsent(session);
        String messageType=(String) map.get("type");
        //System.out.println("type: "+messageType);
        if("updateCart".equals(messageType)){
            System.out.println("tableId: "+tableId);
            String restaurantId=(String) map.get("restaurantId");
            String dishName=(String)map.get("dishName");
            Optional<String> dishOptional=Optional.ofNullable(dishName);
            String actionCode=(String)map.get("actionCode");
            String menuId = "点着玩的";
            if(dishOptional.isPresent()){
                menuId=menuService.getMenuIdByRestaurantIdAndMenuName(restaurantId,dishName);
            }
            orderWSUtil.initializeTableIfNotExists(tableId);
            if(actionCode.equals("1")){
                if(orderWSUtil.menuExists(tableId,menuId)){
                orderWSUtil.addMenu(tableId,menuId);
                }else{
                    orderWSUtil.setHash(tableId,menuId,"1");
                }
            }else if(actionCode.equals("0")){
                if(orderWSUtil.menuExists(tableId,menuId)){
                    orderWSUtil.decrementMenu(tableId,menuId);
                }
            }
            /*List<String> cart=(List<String>) map.get("cart");
            List<String> dishIdList=new ArrayList<>();

            for(String s:cart){
                dishIdList.add(menuMapper.getIdByRestaurantIdAndDishName(restaurantId,s));
            }*/

            //System.out.println("cart: "+cart.toString());
            /*List<Integer> quantities = (List<Integer>) map.get("quantity");
            List<String> quantityStrings = new ArrayList<>();

            if (quantities != null) {
                for (Integer quantity : quantities) {
                    quantityStrings.add(String.valueOf(quantity));
                }
            }*/

            // System.out.println("quantity: "+quantityStrings.toString());

            //System.out.println(cart.size());
            /*for(int i=0; i<dishIdList.size(); i++){
                //System.out.println(i);
                *//*System.out.println("tableId"+tableId);
                System.out.println("cart"+cart.get(i));
                System.out.println("quantity"+quantityStrings.get(i));
                System.out.println(Objects.isNull(orderWSUtil));*//*
                orderWSUtil.setHash(tableId,dishIdList.get(i),quantityStrings.get(i));
            }*/
            System.out.println(tableId);
            System.out.println(orderWSUtil.getMenuMap(tableId).toString());
           /* sessionsMap.get(tableId).stream()
                    .map(WebSocketSession::getId)
                    .forEach(System.out::println);*/
            for(WebSocketSession s:sessionsMap.getOrDefault(tableId,new CopyOnWriteArrayList<>())){
                if(s.isOpen()){
                    s.sendMessage(message);
                    System.out.println(s.getId());
                }
            }
        }else if("orderSubmitted".equals(messageType)){
            Map<Object, Object> hashEntries = orderWSUtil.getMenuMap(tableId);

            List<String> dishCart=new ArrayList<>();
            List<Integer> quantityList=new ArrayList<>();
            Map<String,Object> response=new HashMap<>();
            response.put("dishCart",dishCart);
            response.put("quantity",quantityList);

            for(WebSocketSession s:sessionsMap.getOrDefault(tableId,new CopyOnWriteArrayList<>())){
                if(s.isOpen()){
                    s.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
                }
            }
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        sessions.remove(session);
    }
}

